<!-- form表单，规则详解：https://www.cnblogs.com/kuki/p/15190259.html-->
<!-- slot 放前面 -->
<template>
    <div>
        <el-form :model="column" :rules="rules" ref="formColumn" label-width="120px" size="small" class="formColumn" :disabled="type == 'look'" :key="time">
            <el-form-item>
                <slot></slot>
            </el-form-item>
            <div
                v-for="(item, index) in config"
                :key="index"
                :style="{
                    width: item.span == 2 ? '50%' : item.span == 3 ? '33%' : '100%',
                    display: item.type == '' ? 'none' : 'inline-block'
                }"
            >
                <el-form-item :label="item.fieldCNName" :prop="item.fieldName" :style="{display: item.type == '' ? 'none' : 'block'}">
                    <!-- 普通文本框 -->
                    <el-input
                        style="width: 100%"
                        v-model="column[item.fieldName]"
                        v-if="item.type == 'inputText'"
                        :placeholder="item.placeholder ? item.placeholder : ''"
                        :disabled="item.disabled ?? false"
                        @change="
                            (e) => {
                                inputChange(e, item.fieldName)
                            }
                        "
                    ></el-input>

                    <!-- textarea文本框 -->
                    <el-input
                        style="width: 100%"
                        v-model="column[item.fieldName]"
                        v-if="item.type == 'textarea'"
                        type="textarea"
                        :placeholder="item.placeholder ? item.placeholder : ''"
                        :disabled="item.disabled ?? false"
                    ></el-input>

                    <!-- 下拉框 -->
                    <el-select
                        v-model="column[item.fieldName]"
                        placeholder="请选择"
                        v-if="item.type == 'select'"
                        style="width: 100%"
                        :disabled="item.disabled ?? false"
                        @change="
                            (e) => {
                                selectChange(e, item.fieldName)
                            }
                        "
                    >
                        <el-option :label="select.label" :value="select.value.toString()" v-for="(select, sIndex) in item.itemList" :key="sIndex"></el-option>
                    </el-select>

                    <!-- 日期 -->
                    <el-date-picker
                        :disabled="item.disabled ?? false"
                        v-model="column[item.fieldName]"
                        v-if="item.type == 'date' || item.type == 'datetime'"
                        style="width: 100%"
                        :type="item.type"
                        placeholder="选择日期"
                        :picker-options="pickerOptions"
                        @change="
                            (e) => {
                                dateChange(e, item.fieldName, item.type)
                            }
                        "
                    >
                    </el-date-picker>

                    <!-- 时间 时分秒 -->
                    <el-time-picker
                        :disabled="item.disabled ?? false"
                        v-model="column[item.fieldName]"
                        v-if="item.type == 'time'"
                        style="width: 100%"
                        format="HH:mm:ss"
                        value-format="HH:mm:ss"
                        placeholder="选择时间"
                    >
                    </el-time-picker>

                    <!-- 日期范围 -->
                    <el-date-picker
                        :disabled="item.disabled ?? false"
                        v-model="column[item.fieldName]"
                        v-if="item.type == 'daterange' || item.type == 'datetimerange'"
                        :type="item.type"
                        unlink-panels
                        range-separator="至"
                        start-placeholder="开始日期"
                        end-placeholder="结束日期"
                        :picker-options="rangePickerOptions"
                        @change="
                            (e) => {
                                dateRangeChange(e, item.fieldName, item.type)
                            }
                        "
                    >
                    </el-date-picker>

                    <!-- switch -->
                    <el-switch :disabled="item.disabled ?? false" v-model="column[item.fieldName]" v-if="item.type == 'switch'"></el-switch>

                    <!-- checkbox -->
                    <el-checkbox-group
                        :disabled="item.disabled ?? false"
                        v-model="column[item.fieldName]"
                        v-if="item.type == 'checkbox'"
                        @change="
                            (e) => {
                                checkChange(e, item.fieldName)
                            }
                        "
                    >
                        <el-checkbox
                            :disabled="'ND' == checkItem && item.fieldName == 'options' ? true : item.disabled ?? false"
                            v-for="checkItem in item.itemList.map((t) => t.label)"
                            :label="checkItem"
                            :key="checkItem"
                        >
                            {{ checkItem }}
                        </el-checkbox>
                    </el-checkbox-group>

                    <!-- radio -->
                    <el-radio-group :disabled="item.disabled ?? false" v-model="column[item.fieldName]" v-if="item.type == 'radio'">
                        <el-radio :label="checkItem.value" v-for="(checkItem, index) in item.itemList" :key="index">{{ checkItem.label }}</el-radio>
                    </el-radio-group>

                    <!-- inputNumber -->
                    <el-input
                        :disabled="item.disabled ?? false"
                        style="width: 100%"
                        type="number"
                        :min="item.rules && item.rules.min ? item.rules.min : ''"
                        :max="item.rules && item.rules.max ? item.rules.max : ''"
                        v-model="column[item.fieldName]"
                        v-if="item.type == 'inputNumber'"
                    ></el-input>

                    <!-- upload 原来是图片上传功能，现在改成拍照功能，上传功能隐藏，今后需要在另外加type为uploadImg  -->
                    <div style="display: none">
                        <el-upload
                            v-if="item.type == 'upload'"
                            action="/ccdc/sys/common/upload"
                            list-type="picture-card"
                            :on-preview="handlePictureCardPreview"
                            :file-list="fileList[item.fieldName]"
                            :on-remove="
                                (file, fileList) => {
                                    handleRemove(file, fileList, item.fieldName)
                                }
                            "
                            :multiple="item.multiple"
                            :on-exceed="
                                (file, fileList) => {
                                    handleExceed(file, fileList, item.fieldName)
                                }
                            "
                            :on-success="
                                (file, fileList) => {
                                    handleChange(file, fileList, item.fieldName)
                                }
                            "
                            :accept="item.accept"
                            :limit="item.limit"
                            :headers="headers"
                        >
                            <i class="el-icon-plus"></i>
                        </el-upload>
                    </div>
                    <div v-if="item.type == 'upload'" style="display: inline-block">
                        <div v-if="fileList[item.fieldName].length > 0" style="display: inline-block; float: left">
                            <div
                                v-for="(imgItem, index) in fileList[item.fieldName].map((t) => t.url)"
                                v-bind:key="index"
                                style="display: inline-block; float: left; margin-right: 10px; position: relative"
                            >
                                <el-image style="width: 100px; height: 100px" :src="imgItem" :preview-src-list="fileList[item.fieldName].map((t) => t.url)"></el-image>
                                <i
                                    class="el-icon-circle-close"
                                    title="点击删除图片"
                                    @click="deleteImg(imgItem, item.fieldName)"
                                    v-if="type != 'look'"
                                    style="position: absolute; right: 0; top: 0; color: #999; font-size: 20px; cursor: pointer"
                                ></i>
                            </div>
                        </div>

                        <el-button type="primary" size="mini" @click="showPhoto(item.fieldName)"> <i class="el-icon-plus"></i> 拍照 </el-button>
                    </div>
                </el-form-item>
            </div>

            <el-form-item v-if="type != 'look'">
                <el-button v-if="showIdCard" type="primary" @click="readIdCard">读 卡</el-button>

                <el-button type="primary" @click="submitForm('formColumn')">提 交</el-button>
                <el-button @click="resetForm('formColumn')" v-if="type == 'add'">重 置</el-button>
            </el-form-item>
        </el-form>

        <el-dialog :visible.sync="dialogVisible" append-to-body>
            <img width="100%" :src="dialogImageUrl" alt="" />
        </el-dialog>
    </div>
</template>

<script>
import {PopupCommon} from "@/libs/popupCommon"
import {Utility} from "@/libs/utility"
import moment from "moment"
// 字段对应规则
let formRules = {}
// 配置信息
let formConfig = []
let formColumn = {}
let fileLists = {}
export default {
    components: {},
    data() {
        return {
            // 当前正在编辑的拍照的字段
            curFieldName: "",
            dialogImageUrl: "",
            dialogVisible: false,
            headers: {},
            // 这里会动态创建字段（不知道一个页面会有多少个上传组件） 最终值：fileList:{file1:[{name:"xx",url:"xxx"}],file2:[{name:"xx",url:"xxx"}]}
            fileList: fileLists,
            time: "1",
            // 字段以及字段赋值
            column: formColumn,
            rules: formRules,
            config: formConfig,
            pickerOptions: {
                shortcuts: [
                    {
                        text: "今天",
                        onClick(picker) {
                            picker.$emit("pick", new Date())
                        }
                    },
                    {
                        text: "昨天",
                        onClick(picker) {
                            const date = new Date()
                            date.setTime(date.getTime() - 3600 * 1000 * 24)
                            picker.$emit("pick", date)
                        }
                    },
                    {
                        text: "一周前",
                        onClick(picker) {
                            const date = new Date()
                            date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
                            picker.$emit("pick", date)
                        }
                    }
                ]
            },
            rangePickerOptions: {
                shortcuts: [
                    {
                        text: "最近一周",
                        onClick(picker) {
                            const end = new Date()
                            const start = new Date()
                            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
                            picker.$emit("pick", [start, end])
                        }
                    },
                    {
                        text: "最近一个月",
                        onClick(picker) {
                            const end = new Date()
                            const start = new Date()
                            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
                            picker.$emit("pick", [start, end])
                        }
                    },
                    {
                        text: "最近三个月",
                        onClick(picker) {
                            const end = new Date()
                            const start = new Date()
                            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
                            picker.$emit("pick", [start, end])
                        }
                    }
                ]
            }
        }
    },
    props: ["formConfig", "type", "ReceiveData", "showTepe", "nidShow", "showIdCard", "jianzhu"],
    methods: {
        // 删除图片
        deleteImg(item, fieldName) {
            console.log(item, fieldName)
            let imgList = JSON.parse(JSON.stringify(this.fileList[fieldName]))
            const itemIndex = imgList.findIndex((t) => t.url == item)
            imgList.splice(itemIndex, 1)
            this.fileList[fieldName] = imgList

            let value = this.column[fieldName].split(",")
            const fIndex = value.findIndex((t) => item.indexOf(t) != -1)
            value.splice(fIndex, 1)
            this.column[fieldName] = value.join(",")
        },
        readIdCard() {
            this.$emit("readIdCard", "")
        },

        /** 文件限制 */
        handleExceed(files, fileList, fieldName) {
            PopupCommon.notify("info", `超过文件个数限制（${formConfig.find((t) => t.fieldName == fieldName).limit}），此次上传无效。`)
            console.log(`本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`)
        },
        /** 文件删除 */
        handleRemove(file, fileList, fieldName) {
            // 这里需要注意一下，新增的是：file.response.message，回显的是：file.name，不会有response
            const fileName = typeof file.response != "undefined" ? file.response.message : file.name
            let value = this.column[fieldName].split(",")
            const fIndex = value.findIndex((t) => t == fileName)
            value = value.splice(fIndex + 1, 1)
            this.column[fieldName] = value.join(",")
            console.log(fileList)
        },
        /** 文件选择后的操作 */
        handleChange(file, fileList, fieldName) {
            console.log(fileList, this.column[fieldName])
            let value = this.column[fieldName]
            if (value == "" || value == undefined || typeof value == "undefined" || value == null) {
                value = file.message
            } else {
                value = value + "," + file.message
            }
            this.column[fieldName] = value
            console.log(fileList, this.column[fieldName])
        },
        handlePictureCardPreview(file) {
            this.dialogImageUrl = file.url
            this.dialogVisible = true
        },
        inputChange(e, n) {
            console.log()
            this.$emit("formInputChange", {
                value: e,
                filedName: n,
                allData: this.column
            })
        },
        inputChangeValue(value, columnName) {
            console.log(value, columnName, "value...................")
            // this.column[columnName] = value
            let values = this.$refs["formColumn"].getFieldsValue()
            // 修改需要修改的字段的值
            values[columnName] = value
            // 设置修改后的值
            this.$refs["formColumn"].setFieldsValue(values)
        },

        selectChange(e, name) {
            // 这里返回当前select以及字段的值
            this.$emit("formSelectChange", {
                value: e,
                filedName: name,
                allData: this.column
            })
        },
        checkChange(e, name) {
            // 这里返回当前checkbox以及字段的值
            this.$emit("formCheckChange", {
                value: e,
                filedName: name,
                allData: this.column
            })
        },
        dateChange(value, columnName, type) {
            let format = ""
            if (type == "date") {
                format = "YYYY-MM-DD"
            } else if (type == "datetime") {
                format = "YYYY-MM-DD HH:mm:ss"
            } else if (type == "time") {
                format = "HH:mm:ss"
            }
            this.column[columnName] = moment(value).format(format)
        },
        dateRangeChange(value, columnName, type) {
            let format = type == "daterange" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss"
            if (value) {
                let newValue = []
                newValue.push(moment(value[0]).format(format))
                newValue.push(moment(value[1]).format(format))
                this.column[columnName] = newValue
            }
        },
        submitForm(formName) {
            let that = this
            this.$refs[formName].validate((valid) => {
                if (valid) {
                    that.config.forEach((type) => {
                        if (type.type == "checkbox") {
                            if (that.column[type.fieldName].length > 0) {
                                let newValue = []
                                that.column[type.fieldName].forEach((t) => {
                                    newValue.push(type.itemList.find((b) => b.label == t).value)
                                })
                                this.column[type.fieldName] = newValue.join(",")
                            } else {
                                this.column[type.fieldName] = ""
                            }
                        }

                        if (type.type == "time") {
                            let fValue = this.column[type.fieldName]
                            let finishV = fValue
                            try {
                                finishV = moment(fValue).format("HH:mm:ss")
                                if (finishV.indexOf("date") != -1) {
                                    finishV = fValue
                                }
                            } catch (error) {
                                finishV = fValue
                            }
                            this.column[type.fieldName] = finishV
                        }

                        // 时间范围处理
                        if (type.type == "daterange" || type.type == "datetimerange") {
                            console.log(this.column[type.fieldName])
                            this.column[type.fieldNames[0]] = this.column[type.fieldName][0]
                            this.column[type.fieldNames[1]] = this.column[type.fieldName][1]
                            delete this.column[type.fieldName]
                        }
                    })
                    that.$emit("submit", that.column)
                } else {
                    return false
                }
            })
        },
        resetForm(formName) {
            console.log(formName, "............")
            this.$refs[formName].resetFields()
        },
        // 父组件改变子组件的值 (f是图片的字段名，v是图片的值，只用于图片)
        changeFormValue(d, f) {
            if (f) {
                fileLists[f] = []
                if (f) {
                    const tempFileIds = d[f].split(",")
                    console.log(tempFileIds, "tempFileIds...............")
                    tempFileIds.forEach((item) => {
                        if (item) {
                            fileLists[f].push({
                                name: item,
                                url: Utility.getImgUrl(item)
                            })
                        }
                    })
                }
                formColumn[f] = d[f]
            }
            console.log(d, "d.....")
            this.column = d
        },
        // 改变某个select组件的option的集合值
        changeSelectItemList(list, fieldName) {
            console.log(list, fieldName)
            console.log(formColumn, formConfig)
            formConfig.find((t) => t.fieldName == fieldName).itemList = list
        },
        getFormValue() {
            return this.column
        }
    },
    // 创建之前赋值规则会生效
    beforeCreate() {
        if (this.$options.propsData.jianzhu) {
            // 增加两个特殊的 建筑的
            formRules["jianZhuParentId"] = [
                {
                    required: true,
                    message: "请选择上级建筑",
                    trigger: ["blur", "change"]
                }
            ]
            formRules["jianZhuName"] = [
                {
                    required: true,
                    message: "建筑名称不能为空",
                    trigger: ["blur", "change"]
                }
            ]
        }

        this.time = new Date().getTime()
        // 获取传递过来的规则
        const fcData = this.$options.propsData.formConfig
        if (typeof fcData == "undefined" || fcData.length < 1) {
            PopupCommon.notify("info", "请配置form字段及其规则")
            return
        }
        formConfig = fcData
        const fIndex = formConfig.findIndex((t) => t.fieldName == "optReason")
        if (fIndex > -1) {
            formConfig.splice(fIndex, 1)
        }
        if (this.$options.propsData.type == "edit" && formConfig.findIndex((t) => t.fieldName == "optReason") == -1 && this.$options.propsData.nidShow != "show") {
            // 编辑增加操作原因字段
            // formConfig.push({
            // 	fieldName: "optReason",
            // 	fieldCNName: "操作原因",
            // 	filedValue: "",
            // 	type: "textarea",
            // 	rules: {
            // 		required: true,
            // 	},
            // })
        } else if (this.$options.propsData.type == "look" && formConfig.findIndex((t) => t.fieldName == "optReason") == -1) {
            // 编辑增加操作原因字段
            // formConfig.push({
            // 	fieldName: "optReason",
            // 	fieldCNName: "操作原因",
            // 	filedValue: "",
            // 	disabled: true,
            // 	type: "textarea",
            // })
        }
        let label = ""
        // 规则  formRules
        fcData.forEach((t) => {
            // 下拉框的值这里要处理下：传过来的是id，这里要默认勾选得用name
            if (t.type == "checkbox") {
                console.log(t.type, "checkobx/////")
                if (t.filedValue && t.filedValue.indexOf(",") != -1) {
                    t.filedValue = t.filedValue.split(",")
                }
                if (t.filedValue && t.filedValue.length > 0 && typeof t.filedValue == "object") {
                    let newCBValue = []
                    t.filedValue.forEach((cb) => {
                        try {
                            label = t.itemList.find((cbv) => cbv.value == cb).label
                        } catch (error) {
                            console.log(error.message)
                            label = ""
                        }
                        if (label) {
                            newCBValue.push(label)
                        }
                    })
                    formColumn[t.fieldName] = newCBValue
                } else {
                    if (t.fieldName == "options" && t.fieldCNName == "选择项配置") {
                        formColumn[t.fieldName] = ["ND"]
                    } else {
                        formColumn[t.fieldName] = []
                    }
                }
            } else {
                if (t.type == "switch") {
                    formColumn[t.fieldName] = t.filedValue == "1"
                } else if (t.type == "time") {
                    const tempDate = t.filedValue.split(":")
                    formColumn[t.fieldName] = new Date(2016, 9, 10, tempDate[0], tempDate[1], tempDate[2])
                } else if (t.type == "upload") {
                    fileLists[t.fieldName] = []
                    if (t.filedValue) {
                        const tempFileIds = t.filedValue.split(",")
                        tempFileIds.forEach((item) => {
                            if (item) {
                                fileLists[t.fieldName].push({
                                    name: item,
                                    url: Utility.getImgUrl(item)
                                })
                            }
                        })
                    }
                    formColumn[t.fieldName] = t.filedValue
                } else if (t.type == "select") {
                    if (t.filedValue) {
                        formColumn[t.fieldName] = t.filedValue.toString()
                    } else {
                        formColumn[t.fieldName] = t.filedValue
                    }
                } else {
                    formColumn[t.fieldName] = t.filedValue
                }
            }

            let itemRules = []
            if (t.rules) {
                Object.keys(t.rules).map((r) => {
                    if (r == "required") {
                        itemRules.push({
                            required: true,
                            message: t.fieldCNName + "不能为空"
                        })
                    }
                    if (r == "len") {
                        itemRules.push({
                            len: t.rules["len"],
                            message: `长度为${t.rules["len"]}`
                        })
                    }
                    if (r == "max") {
                        itemRules.push({
                            min: t.rules["min"],
                            max: t.rules["max"],
                            message: `长度在 ${t.rules["min"]} 到 ${t.rules["max"]} 个字符`
                        })
                    }
                    if (r == "type") {
                        // 手机号码
                        if (t.rules[r] == "phone") {
                            itemRules.push({
                                pattern: /^1[3-9]\d{9}$/,
                                message: `请输入正确的手机号码`,
                                trigger: "blur"
                            })
                        }
                        // 座机
                        if (t.rules[r] == "telphone") {
                            itemRules.push({
                                pattern: /\d{3,4}[-]\d{8}/,
                                message: `请输入正确的座机号码：区号-号码`,
                                trigger: "blur"
                            })
                        }
                        // 身份证
                        if (t.rules[r] == "idCard") {
                            itemRules.push({
                                pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
                                message: `请输入正确身份证号码`,
                                trigger: "blur"
                            })
                        }
                        // 邮箱
                        if (t.rules[r] == "email") {
                            itemRules.push({
                                type: "email",
                                message: "请输入正确的邮箱地址",
                                trigger: ["blur", "change"]
                            })
                        }
                    }
                })
            }
            if (itemRules.length > 0) {
                formRules[t.fieldName] = itemRules
            }
        })
    },
    mounted() {
        // let projectTestperiod = window.sessionStorage.getItem("projectTestperiod")
        // if (projectTestperiod) {
        // 	projectTestperiod = JSON.parse(projectTestperiod)
        // 	// 上传时需要
        // 	this.headers = {
        // 		"X-Access-Token": localStorage.getItem("token"),
        // 		pmId: projectTestperiod.projectId,
        // 		expId: projectTestperiod.testId,
        // 		periodNo: projectTestperiod.periodId,
        // 	}
        // } else {
        // 	this.$router.replace({
        // 		name: "userLogin",
        // 	})
        // }
    },
    destroyed() {
        // 清空属性字段，解决切换页面无法输入的bug（因为保留了上一个页面的字段，导致字段不对称）
        // 字段对应规则
        formRules = {}
        // 配置信息
        formConfig = []
        formColumn = {}
    }
}
</script>

<style></style>
